﻿using System;
using System.Collections.Generic;
using System.Linq;

using mvcForum.Core;
using mvcForum.Core.Events;
using mvcForum.Core.Interfaces.Services;

using mvcForum.Web.Helpers;
using mvcForum.Core.Interfaces.Data;
using mvcForum.Core.Interfaces.Events;

namespace mvcForum.Web.Services {

	public class PostService : IPostService {
		private readonly IContext context;
		private readonly IForumAccessService accessService;
		private readonly IEventPublisher eventPublisher;
		private readonly IRepository<Post> postRepo;

		public PostService(IContext context, IForumAccessService accessService, IEventPublisher eventPublisher) {
			this.context = context;
			this.accessService = accessService;
			this.eventPublisher = eventPublisher;
			this.postRepo = this.context.GetRepository<Post>();
		}

		public Post Create(ForumUser author, Topic topic, String subject, String body, String authorIP, String userAgent, String topicUrl, List<String> feedbackOutput, Post replyTo) {
			Post post = null;

			AccessFlag flag = this.accessService.GetAccessFlag(topic.Forum, author);
			// Does the user have post access to the forum?
			if ((flag & AccessFlag.Post) == AccessFlag.Post) {
				// Just a sanity check, is the original post also a post in this topic?
				if (replyTo != null && replyTo.Topic == topic) {
					// Add a new post (as a reply to an existing post!)
					post = new Post(author, topic, subject.Replace("<", "&gt;"), body, authorIP, replyTo);
				}
				else {
					// Add new post in the topic!
					post = new Post(author, topic, subject.Replace("<", "&gt;"), body, authorIP);
				}
				// Let's sort out position!
				post.Position = post.Topic.Posts.Where(p => p.Posted < post.Posted).Count();

				// Let's save the changes!
				this.postRepo.Create(post);
				this.context.SaveChanges();

				NewPostEvent e = new NewPostEvent { PostId = post.Id, TopicId = topic.Id, ForumId = topic.Forum.Id, UserAgent = userAgent, TopicRelativeURL = topicUrl };
				this.eventPublisher.Publish(e);

				IEnumerable<EventFeedback> feedback = e.GetFeedback();
				if (feedback.Any()) {
					foreach (EventFeedback fb in feedback) {
						feedbackOutput.Add(ForumHelper.GetHtmlString(fb.TextKey, fb.Namespace, fb.Arguments).ToString());
					}
				}
			}

			return post;
		}

		public Post Create(ForumUser author, Topic topic, String subject, String body, String authorIP, String userAgent, String topicUrl, List<String> feedbackOutput) {
			return this.Create(author, topic, subject, body, authorIP, userAgent, topicUrl, feedbackOutput, null);
		}
	}
}
